<?php

namespace Dongasai\WkProtoPhp;

/**
 * JSON转换trait
 */
trait JsonSerializableTrait
{
    /**
     * 将对象转换为JSON字符串
     */
    public function toJson(): string
    {
        return json_encode($this->toArray(), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
    }
    
    /**
     * 从JSON字符串创建对象
     */
    public static function fromJson(string $json): static
    {
        $data = json_decode($json, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new \InvalidArgumentException('Invalid JSON: ' . json_last_error_msg());
        }
        return static::fromArray($data);
    }
    
    /**
     * 将对象转换为数组
     */
    public function toArray(): array
    {
        $data = [];
        $reflection = new \ReflectionClass($this);
        $properties = $reflection->getProperties();
        
        foreach ($properties as $property) {
            if ($property->isPrivate() || $property->isProtected()) {
                $property->setAccessible(true);
                $value = $property->getValue($this);
                
                // 处理枚举类型
                if ($value instanceof \UnitEnum) {
                    $value = $value->value;
                }
                
                // 处理Setting对象
                if ($value instanceof \Dongasai\WkProtoPhp\Enums\Setting) {
                    $value = $value->getValue();
                }
                
                $data[$property->getName()] = $value;
            }
        }
        
        return $data;
    }
    
    /**
     * 从数组创建对象
     */
    public static function fromArray(array $data): static
    {
        $instance = new static();
        $reflection = new \ReflectionClass($instance);
        
        foreach ($data as $key => $value) {
            if ($reflection->hasProperty($key)) {
                $property = $reflection->getProperty($key);
                if ($property->isPrivate() || $property->isProtected()) {
                    $property->setAccessible(true);
                    
                    // 处理Setting类型
                    if ($property->getName() === 'setting' && is_int($value)) {
                        $value = new \Dongasai\WkProtoPhp\Enums\Setting($value);
                    }
                    
                    $property->setValue($instance, $value);
                }
            }
        }
        
        return $instance;
    }
}